#include "Util.h"
#include <sys/stat.h>
#include <iostream>
#ifdef _WIN32
#include <windows.h>
#include <direct.h>  // _mkdir
#define MKDIR(path) _mkdir(path)
#else
#include <unistd.h>
#include <sys/types.h>
#define MKDIR(path) mkdir(path, 0777)
#endif
void fbxTool::Util::InitConsole()
{
#ifdef _WIN32
	SetConsoleOutputCP(CP_UTF8);
#else
	setlocale(LC_ALL, "en_US.UTF-8");
#endif // _WIN32
}

bool fbxTool::Util::DirectoryExists(const string& path)
{
	struct stat info;
	if (stat(path.c_str(), &info) != 0) {
		// 路径不存在
		return false;
	}
	if (info.st_mode & S_IFDIR) {
		// 路径是一个目录
		return true;
	}
	// 路径存在，但不是目录
	return false;
}

bool fbxTool::Util::CreateDirectoryIfNotExist(const string& path)
{
	// 支持多级目录创建
	size_t pos = 0;
	string currentPath;

	// 递归创建每个路径段
	while ((pos = path.find('/', pos)) != string::npos) {
		currentPath = path.substr(0, pos);
		if (!DirectoryExists(currentPath)) {
			if (MKDIR(currentPath.c_str()) != 0) {
				cerr << "无法创建目录: " << convertStringFromCurrentCodePageToUTF8(currentPath) << endl;
				return false;
			}
		}
		pos++;
	}

	// 最后创建目标目录（可能是多级目录的最后一个目录）
	if (!DirectoryExists(path)) {
		if (MKDIR(path.c_str()) != 0) {
			cerr << "无法创建目录: " << convertStringFromCurrentCodePageToUTF8(path) << endl;
			return false;
		}
		return true;
	}
	return true;
}

string fbxTool::Util::convertUTF16toUTF8(const wstring& s) { return convertUTF16toUTF8(s.c_str(), static_cast<unsigned int>(s.length())); }

string fbxTool::Util::convertUTF16toUTF8(const wchar_t* s) { return convertUTF16toUTF8(s, static_cast<unsigned int>(wcslen(s))); }

string fbxTool::Util::convertUTF16toUTF8(const wchar_t* source, unsigned sourceLength)
{
#if defined(WIN32) && !defined(__CYGWIN__)
	if (sourceLength == 0)
	{
		return string();
	}

	int destLen = WideCharToMultiByte(CP_UTF8, 0, source, sourceLength, 0, 0, 0, 0);
	if (destLen <= 0)
	{
		return string();
	}

	string sDest(destLen, '\0');
	destLen = WideCharToMultiByte(CP_UTF8, 0, source, sourceLength, &sDest[0], destLen, 0, 0);

	if (destLen <= 0)
	{
		return string();
	}

	return sDest;
#else
	return string();
#endif
}

string fbxTool::Util::convertStringFromCurrentCodePageToUTF8(const char* source, unsigned sourceLength)
{
#if defined(WIN32) && !defined(__CYGWIN__)
	if (sourceLength == 0)
	{
		return string();
	}

	int utf16Length = MultiByteToWideChar(CP_ACP, 0, source, sourceLength, 0, 0);
	if (utf16Length <= 0)
	{
		return string();
	}

	wstring sUTF16(utf16Length, L'\0');
	utf16Length = MultiByteToWideChar(CP_ACP, 0, source, sourceLength, &sUTF16[0], utf16Length);
	if (utf16Length <= 0)
	{
		return string();
	}

	return convertUTF16toUTF8(sUTF16);
#else
	return source;
#endif
}

string fbxTool::Util::convertStringFromCurrentCodePageToUTF8(const string& s) {
	return convertStringFromCurrentCodePageToUTF8(s.c_str(), static_cast<unsigned int>(s.length()));
}

string fbxTool::Util::EscapePath(const string& path)
{
	string result;
	for (size_t i = 0; i < path.size(); ++i) {
		if (path[i] == '/' || path[i] == '\\') {
			result += "\\\\";
		}
		else {
			result += path[i];
		}
	}
	return result;
}
